package es.tikitaka.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;

import es.tikitaka.dao.JugadorService;
import es.tikitaka.dictionary.MunicipioDic;
import es.tikitaka.dictionary.PosicionDic;
import es.tikitaka.dictionary.ProvinciaDic;
import es.tikitaka.domain.Temporada;
import es.tikitaka.domain.equipo.Equipo;
import es.tikitaka.domain.jugador.Jugador;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */
@Name("jugadorService")
public class JugadorServiceImpl implements JugadorService {

	@In
	EntityManager em;

	public JugadorServiceImpl() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Método para obtener todos los jugadores registrados en el sistema
	 * independientemente del estado
	 * 
	 * @return lista de todos los jugadores
	 */
	@SuppressWarnings("unchecked")
	public List<Jugador> getList() {
		List<Jugador> list = null;
		try {
			list = em.createQuery(
					"select j from Jugador j order by j.apellidos,j.nombre")
					.getResultList();
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * Método para obtener los jugadores coincidentes con los criterios de
	 * búsqueda.
	 * 
	 * @param nombre
	 *            Nombre del jugador
	 * @param apellidos
	 *            Apellidos del jugador
	 * @param temporada
	 *            Temporada para la que se tiene datos
	 * @param equipo
	 *            Equipo en el que ha jugado
	 * @param provincia
	 *            Provincia de procedencia
	 * @param municipio
	 *            Municipio de procedencia
	 * @param Edad
	 *            Edad del jugador
	 * @param posicion
	 *            Posición en el terreno de juego
	 * @return lista de jugadores coincidentes con los criterios
	 */
	@SuppressWarnings("unchecked")
	public List<Jugador> buscar(String nombre, String apellidos,
			Temporada temporada, Equipo equipo, ProvinciaDic provincia,
			MunicipioDic municipio, Integer edad, PosicionDic posicion,
			StringBuffer s) {

		List<Jugador> listaJugadores = null;

		try {

			Query q = em.createQuery(s.toString());

			if (nombre != null && nombre.length() > 0) {
				q.setParameter("1", nombre);
			}
			if (apellidos != null && apellidos.length() > 0) {
				q.setParameter("2", apellidos);
			}
			if (edad != null) {
				q.setParameter("3", edad);
			}
			if (temporada != null) {
				q.setParameter("4", temporada.getId());
			}
			if (equipo != null) {
				q.setParameter("5", equipo.getId());
			}
			if (provincia != null) {
				q.setParameter("6", provincia.getId());
			}
			if (municipio != null) {
				q.setParameter("7", municipio.getId());
			}
			if (posicion != null) {
				q.setParameter("8", posicion.getId());
			}

			listaJugadores = q.getResultList();

		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return listaJugadores;
	}

	/**
	 * Método para buscar los jugadores coincidentes con el patrón de búsqueda
	 * 
	 * @param buscar
	 *            Cadena de texto a buscar
	 * @return lista de jugadores coincidentes
	 */
	@SuppressWarnings("unchecked")
	public List<Jugador> buscarActivos(String buscar) {

		List<Jugador> lista = null;

		try {
			lista = em
					.createQuery(
							"select j from Jugador j where upper(j.nombre) like upper('%'||?1||'%') and j.activo = 'true' order by j.nombre")
					.setParameter("1", buscar).getResultList();
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return lista;
	}

	/**
	 * Método para buscar los jugadores coincidentes con el patrón de búsqueda y
	 * que ademas no tenga asociada ya la temporada que se está pasando por
	 * parámetro
	 * 
	 * @param buscar
	 *            Cadena de texto a buscar
	 * @param temporada
	 *            Temporada asociada
	 * @return lista de jugadores coincidentes
	 */
	@SuppressWarnings("unchecked")
	public List<Jugador> buscarActivosSinTemporada(String buscar, int en,
			Temporada temporada) {

		List<Jugador> lista = null;

		try {

			if (en == 1) {
				lista = em
						.createQuery(
								"select j from Jugador j where upper(j.apellidos) like upper('%'||?1||'%') and j.activo = 'true' and j.id not in"
										+ "(select p.jugador from PartJugador p, Temporada t where t.id =?2 and p.temporada = t.id ) order by j.nombre")
						.setParameter("1", buscar).setParameter("2",
								temporada.getId()).getResultList();
			} else {
				lista = em
						.createQuery(
								"select j from Jugador j where upper(j.nombre) like upper('%'||?1||'%') and j.activo = 'true' and j.id not in"
										+ "(select p.jugador from PartJugador p, Temporada t where t.id =?2 and p.temporada = t.id ) order by j.nombre")
						.setParameter("1", buscar).setParameter("2",
								temporada.getId()).getResultList();
			}
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return lista;
	}

	/**
	 * Método que comprueba si existe en el sistema el dni que se pasa como
	 * parámetro
	 * 
	 * @param dni
	 *            DNI a comprobar
	 * @return estado del proceso (true or false)
	 */
	@SuppressWarnings("unchecked")
	public boolean existeDni(String dni) {

		boolean existe = false;

		List<Jugador> list = null;
		try {
			list = em.createQuery("select j from Jugador j where j.dni = ?1")
					.setParameter("1", dni).getResultList();

			if (list != null && list.size() > 0) {
				existe = false;
			} else {
				existe = true;
			}
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return existe;
	}

	/**
	 * Método para obtener todos los jugadores inactivos en el sistema
	 * 
	 * @return lista de todos los jugadores inactivos
	 */
	@SuppressWarnings("unchecked")
	public List<Jugador> getJugadoresInactivos() {
		List<Jugador> list = null;
		try {
			list = em.createQuery(
					"select j from Jugador j order by j.apellidos,j.nombre")
					.getResultList();
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 
	 */
	public Jugador merge(Jugador jugador) {
		em.refresh(jugador);
		return em.merge(jugador);
	}

	/**
	 * Método para eliminar un jugador del sistema
	 * 
	 * @param id
	 *            Id del jugador
	 * @return estado del proceso de borrado (true or false)
	 */
	public boolean delete(Integer id) {
		boolean correcto;
		try {
			Jugador player = em.getReference(Jugador.class, id);
			em.remove(player);
			em.flush();
			correcto = true;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			correcto = false;
		}
		return correcto;
	}

	/**
	 * Método para guardar los cambios sufridos por un jugador del sistema o
	 * para registrar a un nuevo jugador
	 * 
	 * @param jugador
	 *            Jugador a guardar
	 * @return estado del proceso de guardado (true or false)
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public boolean save(Jugador jugador) {
		boolean correcto;
		try {
			em.persist(jugador);
			em.flush();
			correcto = true;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			correcto = false;
		}
		return correcto;
	}
}
